<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import {
	UploadOutlined,
	DeleteOutlined,
	RollbackOutlined,
	EyeOutlined
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'

interface Props {
	modelValue?: string
	showOnly?: boolean
	oldCover?: string
	maxSize?: number // 最大文件大小，单位MB
	accept?: string // 接受的文件类型
}

const props = withDefaults(defineProps<Props>(), {
	modelValue: '',
	showOnly: false,
	oldCover: '',
	maxSize: 5, // 默认5MB
	accept: 'image/*'
})

const emit = defineEmits<{
	'update:modelValue': [value: string | null]
}>()

// 响应式数据
const coverUrl = ref('')
const originalCoverUrl = ref<string | null>(null) // 保存原始图片URL用于撤回
const isUploading = ref(false)
const fileInputRef = ref<HTMLInputElement>()
const previewVisible = ref(false)

// 计算属性
const hasCover = computed(() => !!coverUrl.value && !coverUrl.value.startsWith('data:'))
const isDefaultImage = computed(() => coverUrl.value.startsWith('data:'))
const canRollback = computed(() => {
	// 只有当有原始图片且当前状态与原始状态不同时才显示撤回
	return originalCoverUrl.value && coverUrl.value !== originalCoverUrl.value
})

// 辅助函数
const generateDefaultImage = () => {
	const canvas = document.createElement('canvas')
	canvas.width = 120
	canvas.height = 120
	const ctx = canvas.getContext('2d')
	if (!ctx) return ''

	ctx.fillStyle = 'gray'
	ctx.fillRect(0, 0, 120, 120)

	// 绘制文字
	// const texts = [
	// 	{ content: '120 × 120', color: 'white', yOffset: -10 },
	// 	{ content: '点击上传', color: 'blue', yOffset: 10 }
	// ]

	// texts.forEach(text => {
	// 	ctx.font = '16px Arial'
	// 	ctx.textAlign = 'center'
	// 	ctx.textBaseline = 'middle'
	// 	ctx.fillStyle = text.color
	// 	ctx.fillText(text.content, 60, 60 + text.yOffset)
	// })

	return canvas.toDataURL('image/jpeg')
}

const generateDeleteImage = () => {
	const canvas = document.createElement('canvas')
	canvas.width = 120
	canvas.height = 120
	const ctx = canvas.getContext('2d')
	if (!ctx) return ''

	ctx.fillStyle = 'gray'
	ctx.fillRect(0, 0, 120, 120)

	// 绘制删除状态的文字
	// ctx.font = '16px Arial'
	// ctx.textAlign = 'center'
	// ctx.textBaseline = 'middle'
	// ctx.fillStyle = 'white'
	// ctx.fillText('无 图', 60, 60)

	return canvas.toDataURL('image/jpeg')
}

const resetFileInput = () => {
	if (fileInputRef.value) {
		fileInputRef.value.value = ''
	}
}

const processImageFile = (file: File) => {
	isUploading.value = true

	try {
		// 创建临时URL用于预览
		const objectUrl = URL.createObjectURL(file)
		coverUrl.value = objectUrl

		// 发出事件
		emit('update:modelValue', objectUrl)

		// message.success('图片上传成功')
	} catch (error) {
		console.error('图片处理失败:', error)
		message.error('图片处理失败，请重试')
	} finally {
		isUploading.value = false
		resetFileInput()
	}
}

// 事件处理函数
const handleFileSelect = (event: Event) => {
	if (props.showOnly) return

	const target = event.target as HTMLInputElement
	const file = target.files?.[0]

	if (!file) return

	// 文件类型验证
	if (!file.type.startsWith('image/')) {
		message.error('请选择图片文件')
		resetFileInput()
		return
	}

	// 文件大小验证
	const fileSizeMB = file.size / (1024 * 1024)
	if (fileSizeMB > props.maxSize) {
		message.error(`文件大小不能超过 ${props.maxSize}MB`)
		resetFileInput()
		return
	}

	// 处理文件
	processImageFile(file)
}

const handleUploadClick = () => {
	if (props.showOnly) return
	fileInputRef.value?.click()
}

const handleDelete = () => {
	if (props.showOnly) return

	// 清理URL对象
	if (coverUrl.value.startsWith('blob:')) {
		URL.revokeObjectURL(coverUrl.value)
	}

	coverUrl.value = generateDeleteImage()
	emit('update:modelValue', null)
	// message.success('图片已删除')
}

const handleRollback = () => {
	if (props.showOnly) return

	if (originalCoverUrl.value) {
		// 清理当前URL对象
		if (coverUrl.value.startsWith('blob:')) {
			URL.revokeObjectURL(coverUrl.value)
		}

		coverUrl.value = originalCoverUrl.value
		emit('update:modelValue', originalCoverUrl.value)
		// message.success('已撤回修改')
	}
}

const showPreview = () => {
	if (hasCover.value) {
		previewVisible.value = true
	}
}

const handlePreviewCancel = () => {
	previewVisible.value = false
}

// 初始化
onMounted(() => {
	if (props.modelValue) {
		coverUrl.value = props.modelValue
		originalCoverUrl.value = props.modelValue
	} else if (props.oldCover) {
		coverUrl.value = props.oldCover
		originalCoverUrl.value = props.oldCover
	} else {
		coverUrl.value = generateDefaultImage()
	}
})

// 监听modelValue变化
watch(
	() => props.modelValue,
	newValue => {
		if (newValue) {
			coverUrl.value = newValue
		} else {
			coverUrl.value = generateDeleteImage()
		}
	}
)
</script>

<template>
	<div class="relative w-30 h-30 border border-gray-300 rounded overflow-hidden bg-gray-50">
		<!-- 图片预览 - 保持长宽比居中显示 -->
		<div class="w-full h-full flex items-center justify-center">
			<a-image
				:src="coverUrl"
				:preview="false"
				class="max-w-full max-h-full object-contain" />
		</div>

		<!-- 操作按钮 -->
		<div v-if="!showOnly" class="absolute inset-0 pointer-events-none">
			<!-- 上传按钮 - 默认图片时显示 -->
			<div
				v-if="isDefaultImage"
				class="absolute inset-0 flex items-center justify-center pointer-events-auto cursor-pointer"
				@click="handleUploadClick">
				<div class="text-center">
					<UploadOutlined class="text-6! text-gray-500 mb-2" />
				</div>
			</div>

			<!-- 操作按钮组 - 有图片时显示，或者有撤回操作时显示 -->
			<div
				v-if="hasCover || canRollback"
				class="absolute inset-0 flex flex-col justify-between p-1">
				<!-- 顶部按钮组 -->
				<div class="flex justify-between pointer-events-auto">
					<!-- 左上角：预览按钮 -->
					<EyeOutlined
						v-if="hasCover"
						class="text-white bg-black/50 rounded-full p-1 hover:bg-black/70 cursor-pointer"
						@click="showPreview" />
					<!-- 占位 -->
					<div v-else class="w-6 h-6"></div>

					<!-- 右上角：上传按钮 -->
					<UploadOutlined
						class="text-white bg-black/50 rounded-full p-1 hover:bg-black/70 cursor-pointer"
						@click="handleUploadClick" />
				</div>

				<!-- 底部按钮组 -->
				<div class="flex justify-between pointer-events-auto">
					<!-- 左下角：撤回按钮 -->
					<RollbackOutlined
						v-if="canRollback"
						class="text-white bg-black/50 rounded-full p-1 hover:bg-black/70 cursor-pointer"
						@click="handleRollback" />
					<!-- 占位 -->
					<div v-else class="w-6 h-6"></div>

					<!-- 右下角：删除按钮 -->
					<DeleteOutlined
						v-if="hasCover"
						class="text-white bg-black/50 rounded-full p-1 hover:bg-black/70 cursor-pointer"
						@click="handleDelete" />
				</div>
			</div>
		</div>

		<!-- 加载状态 -->
		<div
			v-if="isUploading"
			class="absolute inset-0 flex items-center justify-center bg-black/50 pointer-events-none">
			<div class="text-white">上传中...</div>
		</div>
	</div>

	<!-- 隐藏的文件输入 -->
	<input
		ref="fileInputRef"
		type="file"
		:accept="accept"
		class="hidden"
		@change="handleFileSelect" />

	<!-- 图片预览模态框 - 保持长宽比 -->
	<a-modal
		v-model:open="previewVisible"
		title="图片预览"
		:footer="null"
		width="80%"
		:closable="true"
		@cancel="handlePreviewCancel">
		<div class="flex justify-center items-center h-[70vh]">
			<a-image
				:src="coverUrl"
				:preview="false"
				class="max-w-full max-h-full object-contain" />
		</div>
	</a-modal>
</template>

<style scoped></style>
